package com.xbongbong.saas.model.impl;

import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.fund.enums.FundSetMenuEnum;
import com.xbongbong.pro.enums.fund.enums.ManageTypeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.saas.domain.dao.FundSetDao;
import com.xbongbong.saas.domain.entity.FundSetEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.FundSetModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author zcp
 * @version v1.0
 * @since v1.0
 */
@Service("fundSetModel")
public class FundSetModelImpl implements FundSetModel {

    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private FundSetDao fundSetDao;

    @Override
    public Integer insert(FundSetEntity entity) throws XbbException {
        Long now = DateTimeUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        return fundSetDao.insert(entity);
    }

    @Override
    public Integer update(FundSetEntity entity) throws XbbException {
        Long now = DateTimeUtil.getInt();
        entity.setUpdateTime(now);
        return fundSetDao.update(entity);
    }

    @Override
    public Integer save(FundSetEntity entity) throws XbbException {

        if(entity.getId() == null || Objects.equals(0L, entity.getId())) {
            return insert(entity);
        }
        return update(entity);
    }

    @Override
    public List<FundSetEntity> findEntitys(Map<String, Object> param) {
        return fundSetDao.findEntitys(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return fundSetDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public FundSetEntity getByRefType(String corpid, Integer refType, Integer type) {
        return fundSetDao.getByRefType(corpid, refType, type, null);
    }

    @Override
    public FundSetEntity getByRefType(String corpid, Integer refType, Integer type, String columns) {
        return fundSetDao.getByRefType(corpid, refType, type, columns);
    }

    @Override
    public Long getModelType(String corpid, XbbRefTypeEnum xbbRefTypeEnum) {
        String key = corpid + SymbolConstant.UNDERLINE + XbbRefTypeEnum.CRM.getCode();
        String modelTypeStr = paasRedisHelper.getValue(RedisPrefixConstant.FUND_SET_MODEL_TYPE, key);
        if (StringUtil.isNotEmpty(modelTypeStr)) {
            return Long.parseLong(modelTypeStr);
        }
        //把资金设置相关信息从数据库读取出，再保存入缓存
        FundSetEntity setEntity = getToRedis(corpid, xbbRefTypeEnum);
        return setEntity.getSysLong10();
    }

    /**
     * 从缓存读取资金设置实体
     * 如果缓存不存在则从数据库读取出，再保存入缓存，方便后续直接从缓存读取使用
     * @param corpid 公司id
     * @param xbbRefTypeEnum 业务类型
     * @return com.xbongbong.saas.domain.entity.FundSetEntity
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @Override
    public FundSetEntity getToRedis(String corpid, XbbRefTypeEnum xbbRefTypeEnum){
        String key = corpid + SymbolConstant.UNDERLINE + XbbRefTypeEnum.CRM.getCode();
        String setObj = paasRedisHelper.getValue(RedisPrefixConstant.FUND_SET_OBJECT, key);
        FundSetEntity setEntity = null;
        if (StringUtil.isNotEmpty(setObj)) {
            setEntity = JsonHelperUtil.parseObject(setObj, FundSetEntity.class);
        }
        if (Objects.nonNull(setEntity)) {
            return setEntity;
        }
        //缓存没有则读库
        setEntity = getByRefType(corpid, xbbRefTypeEnum.getCode(), FundSetMenuEnum.RECEIVABLE_RULES.getType());
        if (Objects.isNull(setEntity)) {
            //缓存和数据库都为空，则置默认实体
            setEntity = new FundSetEntity(xbbRefTypeEnum.getCode());
        }
        //设置相关信息置入缓存
        saveSetInfoToRedis(corpid, setEntity);
        return setEntity;
    }

    /**
     * 把资金设置相关信息保存入缓存
     * @param corpid 公司id
     * @param setEntity 设置实体
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @Override
    public void saveSetInfoToRedis(String corpid, FundSetEntity setEntity){
        Long modelType = ModelTypeEnum.PLAN.getCode();
        Integer manageType = ManageTypeEnum.NONE.getCode();
        if (Objects.nonNull(setEntity)) {
            modelType = setEntity.getSysLong10();
            manageType = setEntity.getManageType();
        }
        /*
         * 放入缓存三个东西
         * 1、设置实体：FundSetEntity，账期条件信息通过从缓存读取该实体后获取
         * 2、公司当前启用模式：modelType
         * 3、管理方式：manageType
         *
         * 注：key为corpid与业务类型code的拼接，即：corpid_XbbRefTypeEnum.CRM.getCode()
         */
        //资金设置实体入缓存
        String key = corpid + SymbolConstant.UNDERLINE + XbbRefTypeEnum.CRM.getCode();
        paasRedisHelper.setValue(RedisPrefixConstant.FUND_SET_OBJECT, key, setEntity, RedisConstant.HUGE_DURATION);
        //把生成规则置入缓存
        paasRedisHelper.setValue(RedisPrefixConstant.FUND_SET_MODEL_TYPE, key, modelType, RedisConstant.HUGE_DURATION);
        //把管理方式置入缓存
        paasRedisHelper.setValue(RedisPrefixConstant.FUND_SET_MANAGE_TYPE, key, manageType, RedisConstant.HUGE_DURATION);
    }
}
